// #include "iot/thing.h"
// #include "board.h"
// #include "audio_codec.h"

// #include <driver/gpio.h>
// #include <esp_log.h>
// #include "driver/ledc.h"


// #define TAG "Motor"


// // Define the PWM parameters
// #define LEDC_TIMER              LEDC_TIMER_1
// #define LEDC_MODE               LEDC_LOW_SPEED_MODE
// #define LEDC_CHANNEL            LEDC_CHANNEL_1
// #define LEDC_DUTY_RES           LEDC_TIMER_13_BIT // 13-bit duty resolution
// #define LEDC_FREQUENCY_BASE     4000          // Base PWM frequency (adjust as needed)

// // Define the notes and their corresponding (approximate and experimental) PWM frequencies
// // These values are highly experimental and unlikely to produce recognizable musical notes.
// // You would need to tune these based on your specific motor's behavior.
// typedef struct {
//     uint32_t frequency;
//     uint32_t duration_ms;
// } note_t;

// note_t twinkle_star[] = {
//     {262, 500}, // C4
//     {262, 500},
//     {392, 500}, // G4
//     {392, 500},
//     {440, 500}, // A4
//     {440, 500},
//     {392, 1000}, // G4 (longer)
//     {349, 500}, // F4
//     {349, 500},
//     {330, 500}, // E4
//     {330, 500},
//     {294, 500}, // D4
//     {294, 500},
//     {262, 1000}, // C4 (longer)
//     {392, 500}, // G4
//     {392, 500},
//     {349, 500}, // F4
//     {349, 500},
//     {330, 500}, // E4
//     {330, 500},
//     {294, 1000}, // D4 (longer)
//     {392, 500}, // G4
//     {392, 500},
//     {349, 500}, // F4
//     {349, 500},
//     {330, 500}, // E4
//     {330, 500},
//     {294, 1000}, // D4 (longer)
//     {262, 500}, // C4
//     {262, 500},
//     {392, 500}, // G4
//     {392, 500},
//     {440, 500}, // A4
//     {440, 500},
//     {392, 1000}, // G4 (longer)
//     {0, 0}      // End marker
// };


// namespace iot {

// class Motor : public Thing {
// private:
//     gpio_num_t gpio_num_ = GPIO_NUM_4;

//     void InitializeMotor() {
//         ESP_LOGI(TAG, "Configuring PWM...");

//         // Configure LEDC timer
//         ledc_timer_config_t ledc_timer = {
//             .speed_mode = LEDC_MODE,
//             .duty_resolution = LEDC_DUTY_RES,
//             .timer_num = LEDC_TIMER,
//             .freq_hz = LEDC_FREQUENCY_BASE, // Initial frequency
//             .clk_cfg = LEDC_AUTO_CLK,
//         };
//         ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));

//         // Configure LEDC channel
//         ledc_channel_config_t ledc_channel = {
//             .gpio_num = GPIO_NUM_4,
//             .speed_mode = LEDC_MODE,
//             .channel = LEDC_CHANNEL,
//             .intr_type = LEDC_INTR_DISABLE,
//             .timer_sel = LEDC_TIMER,
//             .duty = 0, // Initial duty cycle (0% - motor off initially)
//             .hpoint = 0,
//             .flags = { .output_invert = 0 }
//             };
//         ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
    
//         ESP_LOGI(TAG, "Playing Twinkle Twinkle Little Star (very roughly)...");
//     }

// public:
// Motor() : Thing("Motor", "振动马达") {
//         InitializeMotor();

//         methods_.AddMethod("PlayMusic", "播放小星星", ParameterList(), [this](const ParameterList& parameters) {
//             int i = 0;
//             while (twinkle_star[i].duration_ms != 0) {
//                 uint32_t frequency = twinkle_star[i].frequency;
//                 uint32_t duration = twinkle_star[i].duration_ms;
        
//                 ESP_LOGI(TAG, "Setting frequency: %lu Hz, duration: %lu ms", frequency, duration);
        
//                 // Update the PWM frequency
//                 ESP_ERROR_CHECK(ledc_set_freq(LEDC_MODE, LEDC_TIMER, frequency));
        
//                 // Set a non-zero duty cycle to make the motor produce sound
//                 // Adjust the duty cycle (0-8191 for 13-bit resolution) as needed.
//                 // A higher duty cycle means more power to the motor and potentially a louder sound.
//                 ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, 4096)); // 50% duty cycle
//                 ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL));
        
//                 vTaskDelay(pdMS_TO_TICKS(duration));
        
//                 // Optionally set duty cycle to 0 to have silence between notes
//                 ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, 0));
//                 ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL));
//                 vTaskDelay(pdMS_TO_TICKS(50)); // Short pause between notes
        
//                 i++;
//             }
//         });
//     }
// };

// } // namespace iot

// DECLARE_THING(Motor);



#include "iot/thing.h"
#include "board.h"
#include "audio_codec.h"

#include <driver/gpio.h>
#include <esp_log.h>
#include "driver/ledc.h"

#define TAG "Motor"

#define LEDC_MODE LEDC_LOW_SPEED_MODE
#define LEDC_CHANNEL LEDC_CHANNEL_1
#define LEDC_TIMER LEDC_TIMER_1
#define LEDC_GPIO 4 // 振动电机连接的 GPIO 引脚
#define LEDC_FIXED_FREQUENCY 1000 // PWM 频率
// #define DUTY_MAX 8192 // ESP32 LEDC 13-bit 精度，最大占空比
#define LEDC_DUTY_RES           LEDC_TIMER_13_BIT


// 音符持续时间（毫秒）
#define QUARTER_NOTE 400 // 四分音符
#define HALF_NOTE 800    // 二分音符
#define NOTE_GAP 50      // 音符间间隔

// 小星星的音符（频率和持续时间）
typedef struct {
    int freq; // PWM 频率（Hz），模拟音高
    int duty; // 占空比，控制强度
    int duration; // 持续时间（毫秒）
} Note;

// 小星星音符序列（C4=261.63Hz 起，简化频率）
Note twinkle[] = {
    // 第一段: C4 C4 G4 G4 A4 A4 G4
    {262, 4096, QUARTER_NOTE}, {262, 4096, QUARTER_NOTE}, // C4 C4
    {392, 4096, QUARTER_NOTE}, {392, 4096, QUARTER_NOTE}, // G4 G4
    {440, 4096, QUARTER_NOTE}, {440, 4096, QUARTER_NOTE}, // A4 A4
    {392, 4096, HALF_NOTE},                              // G4

    // 第二段: F4 F4 E4 E4 D4 D4 C4
    {349, 4096, QUARTER_NOTE}, {349, 4096, QUARTER_NOTE}, // F4 F4
    {330, 4096, QUARTER_NOTE}, {330, 4096, QUARTER_NOTE}, // E4 E4
    {294, 4096, QUARTER_NOTE}, {294, 4096, QUARTER_NOTE}, // D4 D4
    {262, 4096, HALF_NOTE},                              // C4

    // 第三段: G4 G4 F4 F4 E4 E4 D4
    {392, 4096, QUARTER_NOTE}, {392, 4096, QUARTER_NOTE}, // G4 G4
    {349, 4096, QUARTER_NOTE}, {349, 4096, QUARTER_NOTE}, // F4 F4
    {330, 4096, QUARTER_NOTE}, {330, 4096, QUARTER_NOTE}, // E4 E4
    {294, 4096, HALF_NOTE},                              // D4

    // 第四段: G4 G4 F4 F4 E4 E4 D4
    {392, 4096, QUARTER_NOTE}, {392, 4096, QUARTER_NOTE}, // G4 G4
    {349, 4096, QUARTER_NOTE}, {349, 4096, QUARTER_NOTE}, // F4 F4
    {330, 4096, QUARTER_NOTE}, {330, 4096, QUARTER_NOTE}, // E4 E4
    {294, 4096, HALF_NOTE},                              // D4

    // 第五段: C4 C4 G4 G4 A4 A4 G4
    {262, 4096, QUARTER_NOTE}, {262, 4096, QUARTER_NOTE}, // C4 C4
    {392, 4096, QUARTER_NOTE}, {392, 4096, QUARTER_NOTE}, // G4 G4
    {440, 4096, QUARTER_NOTE}, {440, 4096, QUARTER_NOTE}, // A4 A4
    {392, 4096, HALF_NOTE},                              // G4

    // 第六段: F4 F4 E4 E4 D4 D4 C4
    {349, 4096, QUARTER_NOTE}, {349, 4096, QUARTER_NOTE}, // F4 F4
    {330, 4096, QUARTER_NOTE}, {330, 4096, QUARTER_NOTE}, // E4 E4
    {294, 4096, QUARTER_NOTE}, {294, 4096, QUARTER_NOTE}, // D4 D4
    {262, 4096, HALF_NOTE},                              // C4
};

// 设置 PWM 频率
void set_pwm_freq(int freq) {
    ledc_set_freq(LEDC_MODE, LEDC_TIMER, freq);
}

// 振动函数
void vibrate(int freq, int duty, int duration) {
    ESP_LOGI(TAG, "Vibrating at %d Hz, duty %d for %d ms", freq, duty, duration);
    set_pwm_freq(freq); // 设置振动频率
    ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, duty));
    ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL));
    vTaskDelay(pdMS_TO_TICKS(duration));
    // 停止振动
    ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, 0));
    ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL));
    vTaskDelay(pdMS_TO_TICKS(NOTE_GAP)); // 音符间间隔
}

// 播放小星星
void play_twinkle() {
    for (int i = 0; i < sizeof(twinkle) / sizeof(twinkle[0]); i++) {
        vibrate(twinkle[i].freq, twinkle[i].duty, twinkle[i].duration);
    }
}

namespace iot {

class Motor : public Thing {
private:
    gpio_num_t gpio_num_ = GPIO_NUM_4;

    void InitializeMotor() {
        ESP_LOGI(TAG, "Configuring PWM for vibration motor...");

        // 配置 LEDC 定时器（固定频率）
        ledc_timer_config_t ledc_timer = {
            .speed_mode = LEDC_MODE,
            .duty_resolution = LEDC_DUTY_RES,
            .timer_num = LEDC_TIMER,
            .freq_hz = LEDC_FIXED_FREQUENCY,
            .clk_cfg = LEDC_AUTO_CLK,
        };
        ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));

        // 配置 LEDC 通道
        ledc_channel_config_t ledc_channel = {
            .gpio_num = gpio_num_,
            .speed_mode = LEDC_MODE,
            .channel = LEDC_CHANNEL,
            .intr_type = LEDC_INTR_DISABLE,
            .timer_sel = LEDC_TIMER,
            .duty = 0, // 初始关闭震动
            .hpoint = 0,
            .flags = {.output_invert = 0}
        };
        ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
    }

public:
    Motor() : Thing("Motor", "振动马达") {
        InitializeMotor();

        methods_.AddMethod("PlayRhythm", "播放小星星节奏", ParameterList(), [this](const ParameterList&) {
            ESP_LOGI(TAG, "Playing rhythm...");
            play_twinkle();
        });
    }
};

} // namespace iot

DECLARE_THING(Motor);
